﻿#include "shm_session.h"
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <errno.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <inttypes.h>
#include <pthread.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <list>

#include <json/json.h>
#include <functional>
//processdata
#include "../common/_processdata.h"

//sharememory
#include "../common/sharememory/include/mv_ipc_operator.h"
#include "../common/sharememory/include/ipc_topic.h"
#include "../common/sharememory/include/cmd.h"
#include "../common/sharememory/include/ocr_to_service_event.h"
#include "../common/sharememory/include/vwah_algo_hareware_event.h"
#include "../common/sharememory/include/aiserver_msg.h"

MVIPCPublisher *process_pub;
MVIPCSubscriber *ocr_sub;
MVIPCPublisher *hardware_pub;
MVIPCSubscriber *hardware_sub;
MVIPCPublisher *aiserver_pub;
MVIPCSubscriber *aiserver_sub;

// 初始化共享内存接口
void initSharememoryInterface() {
	process_pub = new MVIPCPublisher(PROCESS_TOPIC);
    hardware_pub = new MVIPCPublisher(WINDOW_ALGO_TO_HARDWARE);
    aiserver_pub = new MVIPCPublisher(AISERVER_TOPIC);
	ocr_sub = new MVIPCSubscriber();
	hardware_sub = new MVIPCSubscriber();
    aiserver_sub = new MVIPCSubscriber();
    getOcrSubProcess();
    getHardwareSubProcess();
    getAIServerSubProcess();
	//toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", "");
}

//切换awtk界面
void pubAwtkProcessEvent(const int iProcess) {
	printf("pubAwtkProcessEvent is %d\n",iProcess);
	RecordEventDate_t cmdInfo;
	switch (iProcess)
    {
    case WELCOME_PAGE:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_WELCOME_PAGE;
        break;

    case CARD_READING:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_PUT_PASSPORT_PAGE;
        break;

    case CARD_STOP_MOVE:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_DO_NO_MOVE_PAGE;
        break;
        
    case FACE_REC:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_IRIS_TIPS_PAGE;
        break;

    case FACE_REC_FULL_SCREEN:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_IRIS_ACT_PAGE;
        break;

     case IRIS_REC:
	 	cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_IRIS_ACT_PAGE;
        break;

    case IRIS_REC_FULL_SCREEN:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_IRIS_ACT_PAGE;
        break;

    case WAIT_PAGE:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_WAIT_PAGE;
        break;

    case VEHICLE_PASSAGE:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_GO_TIP_PAGE;
        break;

    case VEHICLE_EXIT_CHANNEL:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_MANUAL_LANE_PAGE;
        break;

    case GET_VEHICLE_FAILED:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_TRY_AGAIN_PAGE;
        break;
    case GET_VEHICLE_NOT_FILED:
		
        break;

    case CARD_READING_FAILED:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_SACN_PUT_PASSPORT_PAGE;
        break;

    case CARD_READING_SUC:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_TAKE_PASSPORT_PAGE;
        break;

    case CARD_EXPIRED:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_PASSPORT_EXPIRED_PAGE;
        break;
    case FACE_EXPIRED:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_FACE_EXPIRED;
        break;
    case IRIS_FAILED:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_IRIS_FAIL_PAGE;
        break;

    case CLOSE_PAGE:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_SERVICE_STOP;
        break;

    case EQUIPMENT_ABNORMALITY:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_SYSTERN_ERROR_PAGE;
        break;

    case ARTIFICIAL_SERVICES:

        break;
    case GET_VEHICLE_INFO:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_ROLL_DOWN_WINDOW_PAGE;
        break;

    case Enter_Num_People:
		cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_ENTER_NUM_PEOPLE_PAGE;
        break;

    case Psg_Roll_Window:
        cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_PSG_ROLL_DOWN_WINDOW_PAGE;
        break;
    
    case Psg_UpDown_Tip:
        cmdInfo.cmd = CMD_CAM_AWTK_SWITCH_PSG_ROKER_UP_DOWN_PAGE;
        break;

    case Car_Window_Detection:

        break;
    
    default:
        break;
    }
	printf("process_pub data is %d\n",cmdInfo.cmd);
	process_pub->publish(&cmdInfo,sizeof(cmdInfo));
}

//监听OCR消息
void getOcrSubProcess() {
	ocr_sub->subscribe(OCR_CONTROL_TO_SERVICE,std::bind([=](void *data,unsigned int data_size){
            printf("receive ocr msg is %x\n",*(reinterpret_cast<int*>(data)));
            ocr_detect_status *cmdInfo = reinterpret_cast<ocr_detect_status*>(data);
            if (cmdInfo->cmd.cmd_code == CMD_COMMAND_OCR_CONNECT_STATUS) {                              //OCR连接状态
                ocrConnectStatus(cmdInfo->dataCon.isConnect);
            } else if (cmdInfo->cmd.cmd_code == CMD_COMMAND_OCR_DETECT_STATUS) {                     //COR检测状态
                ocrCurrentStatus(cmdInfo->dataDet.index);
            } else if (cmdInfo->cmd.cmd_code == CMD_COMMAND_OCR_DATA_IMG_REPORT) {               //OCR数据
                std::string sFakeDoc = std::to_string(cmdInfo->dataInfo.antifakeLabel);
                std::string sDocType(reinterpret_cast<char*>(cmdInfo->dataInfo.eDocType),strlen(reinterpret_cast<const char*>(cmdInfo->dataInfo.eDocType)));
                std::string sSurname(reinterpret_cast<char*>(cmdInfo->dataInfo.NameFrist),strlen(reinterpret_cast<const char*>(cmdInfo->dataInfo.NameFrist)));
                std::string sForename(reinterpret_cast<char*>(cmdInfo->dataInfo.NameSecond),strlen(reinterpret_cast<const char*>(cmdInfo->dataInfo.NameSecond)));
                std::string sBirthday(reinterpret_cast<char*>(cmdInfo->dataInfo.Birthday),strlen(reinterpret_cast<const char*>(cmdInfo->dataInfo.Birthday)));
                std::string sDateOfExpiry(reinterpret_cast<char*>(cmdInfo->dataInfo.DateOfExpiry),strlen(reinterpret_cast<const char*>(cmdInfo->dataInfo.DateOfExpiry)));
                std::string sNationality(reinterpret_cast<char*>(cmdInfo->dataInfo.Nationality),strlen(reinterpret_cast<const char*>(cmdInfo->dataInfo.Nationality)));
                std::string sDocNumber(reinterpret_cast<char*>(cmdInfo->dataInfo.CardId),strlen(reinterpret_cast<const char*>(cmdInfo->dataInfo.CardId)));
                std::string sSex(reinterpret_cast<char*>(cmdInfo->dataInfo.Sex),strlen(reinterpret_cast<const char*>(cmdInfo->dataInfo.Sex)));

                std::string sOCRData = sFakeDoc + "," + sDocType + "," + sSurname + "," + sForename +
                "," + sBirthday + "," + sDateOfExpiry + "," + sNationality + "," + sDocNumber + "," + sSex;
                ocrDataUpload(sOCRData);
            }
    },std::placeholders::_1,std::placeholders::_2));
}

//监听硬件控制消息
void getHardwareSubProcess() {
	hardware_sub->subscribe(WINDOW_ALGO_TO_HARDWARE,std::bind([=](void *data,unsigned int data_size){
            printf("receive hardware msg is %x\n",*(reinterpret_cast<int*>(data)));
            hardware_algo_detected *cmdInfo = reinterpret_cast<hardware_algo_detected*>(data);
            if (cmdInfo->cmd.cmd_code == CMD_COMMAND_LIFTER_STEPS) {                                            //升降高度
                hardware_lifter_steps *revInfo = reinterpret_cast<hardware_lifter_steps*>(data);
                if (revInfo->data.isControl == false) {
                    //将高度上传给到任务线程
                    liftHeightUpload(revInfo->data.steps);
                }
            } else if (cmdInfo->cmd.cmd_code == CMD_COMMAND_ROLLBACKBTN_STATUS) {             //后退按钮
                backBtnReleaseEvent(1);
            } else if (cmdInfo->cmd.cmd_code == CMD_COMMAND_GATHER_EGG_INTO_PLACE) {      //采集蛋到位
                extendSignal(1);
            } else if (cmdInfo->cmd.cmd_code == CMD_COMMAND_PASSENGER_NUM) {                         //按键人数
                hardware_passenger_num *revInfo = reinterpret_cast<hardware_passenger_num*>(data);
                passagerNumUpload(revInfo->data.numPeg);
            } else if (cmdInfo->cmd.cmd_code == CMD_COMMAND_ALGO_DETECT_SUCCEED) {          //算法车窗检测成功

            } else if (cmdInfo->cmd.cmd_code == CMD_COMMAND_HW_CONNECT_STATUS) {
                hardware_connect_status *hwInfo = reinterpret_cast<hardware_connect_status*>(data);
                acquisitionConnectStatus(hwInfo->connectStatus);
            }else if (cmdInfo->cmd.cmd_code == CMD_COMMAND_HW_FAR_FROM_CAR) {
                far_from_car *hwInfo1 = reinterpret_cast<far_from_car*>(data);
                vehcleDistanceParam(hwInfo1->data.motorDescent,hwInfo1->data.widthDistance);
            }
    },std::placeholders::_1,std::placeholders::_2));
}

//监听AIServer消息
void getAIServerSubProcess() {
    aiserver_sub->subscribe(AISERVER_TOPIC,std::bind([=](void *data,unsigned int data_size){
        printf("receive aiserver msg is %x\n",*(reinterpret_cast<int*>(data)));
        AiserverEventCmd *cmdInfo = reinterpret_cast<AiserverEventCmd*>(data);
        if (cmdInfo->cmd_info.cmd_code == CMD_CAM_FACE_RESULT_SUCCESS) {
            std::string sFaceData = "";
            sFaceData = std::to_string(cmdInfo->faceInfo.faceResult) + "," + std::to_string(cmdInfo->faceInfo.eyeOpen) + "," +
            std::to_string(cmdInfo->faceInfo.eyesScore) + "," + std::to_string(cmdInfo->faceInfo.faceScore) + "," + 
            std::to_string(cmdInfo->faceInfo.faceClarity) + "," + std::to_string(cmdInfo->faceInfo.faceBrightness);
            aiserverUploadEvent(8,sFaceData);
        } else if (cmdInfo->cmd_info.cmd_code == CMD_CAM_FACE_RESULT_FAIL) {
            //传默认值
            aiserverUploadEvent(9,"N");
        } else if (cmdInfo->cmd_info.cmd_code == CMD_CAM_IRIS_RESULT_SUCCESS) {
            std::string sIrisData = "";
            sIrisData = std::to_string(cmdInfo->irisInfo.irisResult) + "," + std::to_string(cmdInfo->irisInfo.irisScore) + "," + std::to_string(cmdInfo->irisInfo.irisClarity) +
            "," + std::to_string(cmdInfo->irisInfo.irisQuality) + "," + std::to_string(cmdInfo->irisInfo.irisBrightness);
            aiserverUploadEvent(10,sIrisData);
        } else if (cmdInfo->cmd_info.cmd_code == CMD_CAM_IRIS_RESULT_FAIL) {
            //传默认值
            std::string sIrisData = "";
            sIrisData = std::to_string(cmdInfo->irisInfo.irisResult) + "," + std::to_string(cmdInfo->irisInfo.irisScore) + "," + std::to_string(cmdInfo->irisInfo.irisClarity) +
            "," + std::to_string(cmdInfo->irisInfo.irisQuality) + "," + std::to_string(cmdInfo->irisInfo.irisBrightness);
            aiserverUploadEvent(11,sIrisData);
        } else if (cmdInfo->cmd_info.cmd_code    == CMD_COMMAND_IPC_PROCESS_CRASH) {
            process_info *processInfo = reinterpret_cast<process_info*>(data);
            processMonitor(processInfo->process_index,false);
        } else if (cmdInfo->cmd_info.cmd_code == CMD_COMMAND_PROCESS_RECOVER) {
            process_info *processInfo = reinterpret_cast<process_info*>(data);
            processMonitor(processInfo->process_index,true);
        }
    },std::placeholders::_1,std::placeholders::_2));
}

//一体柜流程控制
void hardwareProcessCtrl(bool bStart, bool bCarWindowDetc, int iDirect) {
    hardware_process_control cmdInfo;
    cmdInfo.cmd.cmd_code = CMD_COMMAND_HW_CONTROL;
    cmdInfo.data.isCarWindowDetect = bCarWindowDetc;
    cmdInfo.data.isRun = bStart;
    cmdInfo.data.deviceLocation = iDirect;
    hardware_pub->publish(&cmdInfo,sizeof(cmdInfo));
    InfoL << "hardwareProcessCtrl: " << bStart;
}

//采集蛋灯控控制
void hardwareLightCtrl(int iLight) {
    hardware_light_control cmdInfo;
    cmdInfo.cmd.cmd_code = CMD_COMMAND_LIGHT_CONTROL;
    cmdInfo.data.lightColor = iLight;
    hardware_pub->publish(&cmdInfo,sizeof(cmdInfo));
    if (iLight == 0) {
        InfoL << "补光灯控制: 关闭";
    } else if (iLight == 1) {
        InfoL << "补光灯控制: 红灯";
    } else if (iLight == 2) {
        InfoL << "补光灯控制: 绿灯";
    } else if (iLight == 3) {
        InfoL << "补光灯控制: 白灯";
    }
}

//采集蛋升降控制
void hardwareHeightCtrl(int iHeight) {
    hardware_lifter_steps cmdInfo;
    cmdInfo.cmd.cmd_code = CMD_COMMAND_LIFTER_STEPS;
    cmdInfo.data.isControl = true;
    cmdInfo.data.steps = iHeight;
    hardware_pub->publish(&cmdInfo,sizeof(cmdInfo));
    InfoL << "hardwareHeightCtrl: " << iHeight;
}

//人脸虹膜流程结束
void irisCameraCloseCtrl() {
    AiserverEventCmd cmdInfo;
    cmdInfo.cmd_info.cmd_code = CMD_CAM_AWTK_IRIS_DEVICE_CLOSE;
    aiserver_pub->publish(&cmdInfo,sizeof(cmdInfo));
    InfoL << "发送人脸虹膜采集结束流程";
}

//人脸虹膜采集流程
void faceirisAcProcess(const int iProcess) {
    AiserverEventCmd cmdInfo;
    if (iProcess == FACE_REC) {
        cmdInfo.cmd_info.cmd_code = CMD_CAM_AWTK_SWITCH_IRIS_TIPS_PAGE;
        InfoL << "Face acquisition workflow";
    } else if (iProcess == IRIS_REC) {
       cmdInfo.cmd_info.cmd_code =  CMD_CAM_AWTK_SWITCH_IRIS_ACT_PAGE;
       InfoL << "Iris acquisition workflow";
    }
    aiserver_pub->publish(&cmdInfo,sizeof(cmdInfo));
}

//获取OCR当前状态
void getOcrConnectionStatus() {
    hardware_algo_detected cmdInfo;
    cmdInfo.cmd.cmd_code = CMD_COMMAND_GET_OCR_STATUS;
    hardware_pub->publish(&cmdInfo,sizeof(cmdInfo));
    InfoL << "获取OCR当前连接状态";
}

//OCR连接状态
void ocrConnectStatus(bool bConnect) {
    InfoL << "ocrConnectStatus:" << bConnect;
    int iConnect = static_cast<int>(bConnect);
    std::string str = std::to_string(iConnect);
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", 1,str);
}

//采集柜下位机连接状态
void acquisitionConnectStatus(bool bConnect) {
    InfoL << "acquisitionConnectStatus:" << bConnect;
    int iConnect = static_cast<int>(bConnect);
    std::string str = std::to_string(iConnect);
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", 12,str);
}

//OCR当前状态 0:读取失败 1:读取成功 2:正在读取证件 3:证件已拿开
void ocrCurrentStatus(int iStatus) {
    InfoL << "ocrCurrentStatus:" << iStatus;
    std::string str = std::to_string(iStatus);
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", 2,str);
}

//OCR数据
void ocrDataUpload(const std::string sData) {
    InfoL << "ocrDataUpload:" << sData;
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", 3,sData);
}

//返回按键按下
void  backBtnReleaseEvent(const int iFlag) {
    InfoL << "触发回退流程按键";
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", 4,std::to_string(iFlag));
}

//升降高度上传
void liftHeightUpload(const int iHeight) {
    InfoL << "升降机高度上传:" << iHeight;
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", 5,std::to_string(iHeight));
}

//机械臂伸出到位信号
void extendSignal(const int iFlag) {
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", 6,std::to_string(iFlag));
    InfoL << "采集蛋伸出到位 <<<<<<<<<<<<<<<<<";
}

//按键人数上传
void passagerNumUpload(const int iNum) {
    InfoL << "采集蛋按键人数上传 :" << iNum;
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", 7,std::to_string(iNum));
}

//人脸虹膜数据采集事件
void aiserverUploadEvent(const int iCmd, const std::string sData) {
    if (iCmd == 8) {                //人脸采集成功
        InfoL << "aiserverUploadEvent: CMD_CAM_FACE_RESULT_SUCCESS";
    } else if (iCmd == 9) {    //人脸采集失败
        InfoL << "aiserverUploadEvent: CMD_CAM_FACE_RESULT_FAIL";
    } else if (iCmd == 10) {  //虹膜采集成功
        InfoL << "aiserverUploadEvent: CMD_CAM_IRIS_RESULT_SUCCESS";
    } else if (iCmd == 11) {  //虹膜采集失败
        InfoL << "aiserverUploadEvent: CMD_CAM_IRIS_RESULT_FAIL";
    }
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", iCmd,sData);
}

void processMonitor(int iProcess, bool bOnline) {
    if (iProcess == 0) {
        InfoL << "mvRender_drm online status: " << bOnline;
    } else if (iProcess == 1) {
        InfoL << "mvAcquisitionServer online status: " << bOnline;
    } else if (iProcess == 2) {
        InfoL << "mvHCServer online status: " << bOnline;
    } else if (iProcess == 3) {
        InfoL << "mvAIServer online status: " << bOnline;
    } else if (iProcess == 4) {
        InfoL << "mvLaneGuidance online status: " << bOnline;
    } else if (iProcess == 5) {
        InfoL << "mvAudioServer online status: " << bOnline;
    } else if (iProcess == 6) {
        InfoL << "mvVideoCall online status: " << bOnline;
    }
}

//测试
void facePubEvent() {
    AiserverEventCmd cmdInfo;
    cmdInfo.cmd_info.cmd_code = CMD_CAM_FACE_RESULT_SUCCESS;
    cmdInfo.faceInfo.eyeOpen = 1;
    cmdInfo.faceInfo.eyesScore = 90;
    cmdInfo.faceInfo.faceBrightness = 50;
    cmdInfo.faceInfo.faceClarity = 50;
    cmdInfo.faceInfo.faceResult = 1;
    cmdInfo.faceInfo.faceScore = 70;
    aiserver_pub->publish(&cmdInfo,sizeof(cmdInfo));
    InfoL << "facePubEvent success";
}

void irisPubEvent() {
    AiserverEventCmd cmdInfo;
    cmdInfo.cmd_info.cmd_code = CMD_CAM_IRIS_RESULT_SUCCESS;
    cmdInfo.irisInfo.irisBrightness = 50;
    cmdInfo.irisInfo.irisClarity = 90;
    cmdInfo.irisInfo.irisQuality = 80;
    cmdInfo.irisInfo.irisResult = 1;
    cmdInfo.irisInfo.irisScore = 90;
    aiserver_pub->publish(&cmdInfo,sizeof(cmdInfo));
    InfoL << "irisPubEvent success";
}

void vehcleDistanceParam(int height,int width){

 InfoL << "车辆距离参数上报 ，高度值 ：" << height <<"，宽度值 ：" <<width;
    std ::string distaStr = std::to_string(height) + "," + std::to_string(width);
    toolkit::NoticeCenter::Instance().emitEvent("shm_sub_data", 13 ,distaStr);

}